package com.rjkj.medicalwaste.ui.storage

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.rjkj.medicalwaste.MainActivity
import com.rjkj.medicalwaste.R
import com.rjkj.medicalwaste.base.BaseFragment
import com.rjkj.medicalwaste.bean.CodeType
import com.rjkj.medicalwaste.bean.GarbageBean
import com.rjkj.medicalwaste.bean.GarbageStatus
import com.rjkj.medicalwaste.bean.ReviewWeightState
import com.rjkj.medicalwaste.database.GarbageSetReviewAndBoxed
import com.rjkj.medicalwaste.database.GarbageSetReviewAndBoxedAddUser
import com.rjkj.medicalwaste.databinding.FragmentStorageScanBinding
import com.rjkj.medicalwaste.livedatabus.LiveDataBus
import com.rjkj.medicalwaste.utils.StrUtils
import com.rjkj.medicalwaste.utils.TimeUtils
import com.rjkj.medicalwaste.viewmodels.StorageScanViewModel
import com.rjkj.medicalwaste.viewmodels.UnBoxedViewModel
import com.rjkj.medicalwaste.viewmodels.UserViewModel
import com.rjkj.medicalwaste.viewmodels.provider.MainViewModelProvider
import com.rjkj.zxinglibrary.zxing.android.CaptureActivity
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


class StorageScanFragment : BaseFragment<FragmentStorageScanBinding>() {
    private val viewModel: StorageScanViewModel by viewModels()
    private val userViewModel: UserViewModel by activityViewModels {
        MainViewModelProvider.provideUserModel(requireContext())
    }
    private val unBoxedViewModel: UnBoxedViewModel by viewModels {
        MainViewModelProvider.provideUnBoxedModel(requireContext())
    }
    private lateinit var startActivity: ActivityResultLauncher<Intent>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startActivity =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                val resultCode = it.resultCode
                if (resultCode == Activity.RESULT_OK) {
                    val data = it.data?.extras?.getString("codedContent") ?: ""
                    Log.e(TAG, "onCreate: ${resultCode}+${data}")
                    doScanCode(data)
                } else {
                    showTip("扫码失败")
                }
            }

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val binding = FragmentStorageScanBinding.inflate(inflater, container, false)
        binding.scanData = viewModel
        binding.lifecycleOwner = viewLifecycleOwner
        onSubscribeUi(binding)
        initKeyEvent()
        return binding.root
    }

    override fun dealCustomScanData(data: String) {
        super.dealCustomScanData(data)
        doScanCode(data)
    }

    override fun onSubscribeUi(binding: FragmentStorageScanBinding) {
        initTip(viewModel)
        initDialog(userViewModel)
        binding.pic.setOnClickListener {
            scanWithCustomUI()
        }
        binding.tvStagingRoom.setOnClickListener {
            scanWithCustomUI()
        }
        LiveDataBus.get().with(MainActivity.SCAN_DATA, String::class.java)
            .observe(viewLifecycleOwner, {
                doScanCode(it)

            })
    }

    private fun doScanCode(s: String) {
        checkCode(s).let { type ->
            if (type == CodeType.StagingRoom) {
                userViewModel.checkLogin(s).observe(viewLifecycleOwner, { user ->
                    if (user != null) {
                        viewModel.stagingRoom.value = user.name
                        userViewModel.stagingRoomUser.value = user
                        lifecycleScope.launch {
                            if (userViewModel.setting.value?.infoMode == 1||userViewModel.setting.value?.infoMode == 2) {
                                userViewModel.uploadEvent.value = true
                                val userCode = userViewModel.cleanerUser.qrcode
                                val reviewTime = TimeUtils.getYMDHMSTime()
                                delay(1000L)
                                val garbageBoxTime = TimeUtils.getYMDHMSTime()
                                val onlyBoxCodeSet = mutableSetOf<String>()
                                // TODO: 2021/6/30 手机模式一键入库
                                val stateGarbage = unBoxedViewModel.repository.getStateGarbage(
                                    userViewModel.hospitalId.value
                                        ?: "",
                                    GarbageStatus.collect
                                ).map { value ->
                                    GarbageSetReviewAndBoxedAddUser(
                                        id = value.id,
                                        garbageUserStatus = GarbageStatus.boxed,
                                        garbageQRCode = value.garbageQRCode,
                                        garbageBoxQRCode = "2${userViewModel.getSerial()}${
                                            getBoxCode(
                                                StrUtils.genRandomNum(12),
                                                onlyBoxCodeSet
                                            )
                                        }",
                                        garbageBoxDeviceSN = userViewModel.getSerial(),
                                        garbageBoxTime = garbageBoxTime,
                                        garbageBoxType = value.garbageType,
                                        reviewWeightState = ReviewWeightState.CheckSuccess,
                                        reviewDeviceSN = userViewModel.getSerial(),
                                        reviewWeight = "0",
                                        reviewType = "0",
                                        reviewTime = reviewTime,
                                        boxCleanerQRCode = userCode,
                                        reviewCleanerQRCode = userCode,
                                        garbageBoxWeight = value.garbageWeight,
                                        garbageCNT = 1,
                                        reviewStorageQRCode = user.qrcode
                                        )
                                }

                                unBoxedViewModel.repository.updateGarbageSetReviewAndBoxedAddUserList(
                                    stateGarbage
                                )
                                val findGarbageByBoxTime =
                                    unBoxedViewModel.repository.findGarbageByBoxTime(garbageBoxTime)
                                userViewModel.uploadGarbage(
                                    garbageBeanList = findGarbageByBoxTime,
                                    successState = GarbageBean.boxState,
                                    failState = GarbageBean.nullState
                                )
                                userViewModel.uploadEvent.value = true
                                showTip("入库装箱成功")
                                delay(500)
                                requireActivity().onBackPressed()
                            } else {
                                viewModel.tips.value = "登录成功！"
                                delay(250L)
                                findNavController().navigate(R.id.action_storageScanFragment_to_storageFunctionFragment)
                            }
                        }
                    } else {
                        viewModel.stagingRoom.value = ""
                        viewModel.tips.value = "未查询到该用户！"
                    }
                })
            } else {
                showTip("请勿扫描${type.alias}")
            }
        }
    }

    private fun getBoxCode(code: String, strSet: MutableSet<String>): String {
        return if (strSet.add(code)) {
            code
        } else {
            getBoxCode(StrUtils.genRandomNum(12), strSet)

        }
    }

}